/**
 * @file Table_Driven_06.c
 * 
 * @brief 
 *          通过表格驱动的方式实现参数的读写接口
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

// 参数类型定义
typedef enum {
    PARAM_TYPE_INT,
    PARAM_TYPE_UINT,
    PARAM_TYPE_FLOAT,
    PARAM_TYPE_STRING,
    PARAM_TYPE_BOOL
} ParamType;

// 参数值定义（联合体节省空间）
typedef union {
    int     i_val;
    unsigned int u_val;
    float   f_val;
    char    s_val[32];
    bool    b_val;
} ParamValue;

// 参数结构体
typedef struct {
    char param_name[25];   // 参数名
    ParamType param_type;  // 参数类型
    ParamValue param_value;// 参数值
} Param;

// 参数表（静态定义，实际项目中可放在 flash / eeprom 中）
#define PARAM_TABLE_SIZE 5
static Param param_table[PARAM_TABLE_SIZE] = {
    {"param1", PARAM_TYPE_INT,   {.i_val = 0}},
    {"param2", PARAM_TYPE_UINT,  {.u_val = 0}},
    {"param3", PARAM_TYPE_FLOAT, {.f_val = 0.0f}},
    {"param4", PARAM_TYPE_STRING,{.s_val = "default"}},
    {"param5", PARAM_TYPE_BOOL,  {.b_val = false}}
};

// 根据名字查找参数索引
static int find_param_index(const char *name)
{
    for (int i = 0; i < PARAM_TABLE_SIZE; i++) {
        if (strcmp(param_table[i].param_name, name) == 0) {
            return i;
        }
    }
    return -1; // 没找到
}

// 写入参数接口
bool set_param(const char *name, const char *value_str)
{
    int idx = find_param_index(name);
    if (idx < 0) return false;

    Param *p = &param_table[idx];
    switch (p->param_type) {
    case PARAM_TYPE_INT:
        p->param_value.i_val = atoi(value_str);
        break;
    case PARAM_TYPE_UINT:
        p->param_value.u_val = (unsigned int)strtoul(value_str, NULL, 10);
        break;
    case PARAM_TYPE_FLOAT:
        p->param_value.f_val = strtof(value_str, NULL);
        break;
    case PARAM_TYPE_STRING:
        strncpy(p->param_value.s_val, value_str, sizeof(p->param_value.s_val)-1);
        p->param_value.s_val[sizeof(p->param_value.s_val)-1] = '\0';
        break;
    case PARAM_TYPE_BOOL:
        if (strcmp(value_str, "true") == 0 || strcmp(value_str, "1") == 0)
            p->param_value.b_val = true;
        else
            p->param_value.b_val = false;
        break;
    default:
        return false;
    }
    return true;
}

// 获取参数接口（以字符串形式返回，方便统一处理）
bool get_param(const char *name, char *out_str, size_t out_size)
{
    int idx = find_param_index(name);
    if (idx < 0) return false;

    Param *p = &param_table[idx];
    switch (p->param_type) {
    case PARAM_TYPE_INT:
        snprintf(out_str, out_size, "%d", p->param_value.i_val);
        break;
    case PARAM_TYPE_UINT:
        snprintf(out_str, out_size, "%u", p->param_value.u_val);
        break;
    case PARAM_TYPE_FLOAT:
        snprintf(out_str, out_size, "%f", p->param_value.f_val);
        break;
    case PARAM_TYPE_STRING:
        snprintf(out_str, out_size, "%s", p->param_value.s_val);
        break;
    case PARAM_TYPE_BOOL:
        snprintf(out_str, out_size, "%s", p->param_value.b_val ? "true" : "false");
        break;
    default:
        return false;
    }
    return true;
}

// ---------------- 测试 ----------------
int main(void)
{
    char buffer[64];

    // 设置参数
    set_param("param1", "123");
    set_param("param3", "45.67");
    set_param("param4", "hello");
    set_param("param5", "true");

    // 读取参数
    if (get_param("param1", buffer, sizeof(buffer)))
        printf("param1 = %s\n", buffer);
    if (get_param("param3", buffer, sizeof(buffer)))
        printf("param3 = %s\n", buffer);
    if (get_param("param4", buffer, sizeof(buffer)))
        printf("param4 = %s\n", buffer);
    if (get_param("param5", buffer, sizeof(buffer)))
        printf("param5 = %s\n", buffer);

    return 0;
}
